package com.ruoyi.iot;

import com.ruoyi.data.domain.TdataHtEq;
import com.ruoyi.data.domain.TdataHtWg;
import com.ruoyi.data.domain.TdataRtRs;
import com.ruoyi.data.service.ITdataHtEqService;
import com.ruoyi.data.service.ITdataHtWgService;
import com.ruoyi.data.service.ITdataRtRsService;
import com.ruoyi.iot.client.NioClient;
import com.ruoyi.param.domain.TparamEq;
import com.ruoyi.param.domain.TparamTm;
import com.ruoyi.param.domain.TparamTp;
import com.ruoyi.param.domain.TparamUe;
import com.ruoyi.param.service.ITparamEqService;
import com.ruoyi.param.service.ITparamTmService;
import com.ruoyi.param.service.ITparamTpService;
import com.ruoyi.param.service.ITparamUeService;
import lombok.Setter;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;

@Slf4j
@Accessors(chain = true)
public abstract class WebTasksCallBack implements NioClient.PortCallback {

    private final String roomId;

    @Setter
    private ITdataRtRsService tdataRtRsService;

    @Setter
    private ITdataHtEqService tdataHtEqService;

    @Setter
    private ITdataHtWgService tdataHtWgService;

    @Setter
    private ITparamUeService tParamUeService;

    @Setter
    private ITparamTpService tParamTpService;

    @Setter
    private ITparamTmService tParamTmService;

    @Setter
    private ITparamEqService tparamEqService;

    @Setter
    private TparamTp tparamTp;

    public WebTasksCallBack(String roomId) {
        this.roomId = roomId;
    }

    public abstract void callBack(boolean res);

    // 当前组合有功总电能
    @Override
    public void readTotalEnergy(BigDecimal totalW, BigDecimal positiveW, BigDecimal negativeW, BigDecimal v, BigDecimal a, BigDecimal w, BigDecimal factor, BigDecimal rate, BigDecimal reactiveW, BigDecimal apparentW) {
        if (tparamEqService != null) {
            tparamEqService.updateByRoomIdSelective(new TparamEq().setRoomId(roomId)
                    .setTotalEq(w).setUpdateDt(LocalDateTime.now()));
        }
        if (tdataHtEqService != null) {
            tdataHtEqService.updateByRoomIdSelective(new TdataHtEq().setRoomId(roomId).setTotalEq(w).setDt(LocalDateTime.now()));
        }
        if (tdataRtRsService != null) {
            tdataRtRsService.updateByRoomIdSelective(new TdataRtRs().setRoomId(roomId).setDt(LocalDateTime.now())
                    .setRunStatus(1).setVol(v).setCur(a)
                    .setYggl(w).setLoopEq(totalW)
            );
        }
        callBack(true);
    }

    // 断电
    @Override
    public void writeOutage() {
        if (tdataRtRsService != null) {
            tdataRtRsService.updateByRoomIdSelective(new TdataRtRs().setRoomId(roomId).setRunStatus(1).setWorkStatus(0)
                    .setDt(LocalDateTime.now()).setStopReason(6));
        }
        if (tParamTpService != null) {
            tParamTpService.updateByRoomIdSelective(new TparamTp().setRoomId(roomId).setUpdateDt(LocalDateTime.now()).setRunType(0));
        }
        callBack(true);
    }

    // 通电
    @Override
    public void writeElectrify() {
        if (tdataRtRsService != null) {
            tdataRtRsService.updateByRoomIdSelective(new TdataRtRs().setRoomId(roomId).setRunStatus(1).setWorkStatus(2)
                    .setDt(LocalDateTime.now()).setStopReason(0));
        }
        if (tParamTpService != null) {
            tParamTpService.updateByRoomIdSelective(new TparamTp().setRoomId(roomId).setUpdateDt(LocalDateTime.now()).setRunType(0));
        }
        callBack(true);
    }

    // 继电器状态字 有恶性负载标志
    @Override
    public void readMalignantLoadState(int state) {
        if (tdataHtWgService != null && state == 1) {
            tdataHtWgService.updateByRoomIdSelective(new TdataHtWg().setRoomId(roomId).setWgReason(1L).setWgPower(new BigDecimal(1)));
        }
        callBack(true);
    }

    // 继电器状态字 总功率超限标志
    @Override
    public void readTotalPowerState(int state) {
        callBack(true);
    }

    // 继电器状态字 定时断电标志
    @Override
    public void readPeriodsState(int state) {
        callBack(true);
    }

    // 校对时间
    @Override
    public void readProofreadTime(int second, int minute, int hour, int week, int day, int month, int year) {
        if (tParamTmService != null) {
            LocalDateTime now = LocalDateTime.now();
            tParamTmService.updateByRoomIdSelective(new TparamTm().setRoomId(roomId)
                    .setSendTm(LocalDateTime.of(year, month, day, hour, minute, second)).setUpdateDt(now).setWeek(String.valueOf(now.getDayOfWeek().getValue()))
            );
        }
        callBack(true);
    }

    // 校对时间
    @Override
    public void writeProofreadTime() {
        if (tParamTmService != null) {
            LocalDateTime now = LocalDateTime.now();
            int year = now.getYear();
            int month = now.getMonth().getValue();
            int day = now.getDayOfMonth();
            int week = now.getDayOfWeek().getValue();
            int hour = now.getHour();
            int minute = now.getMinute();
            int second = now.getSecond();

            tParamTmService.updateByRoomIdSelective(new TparamTm().setRoomId(roomId)
                    .setSendTm(LocalDateTime.of(year, month, day, hour, minute, second)).setUpdateDt(now).setWeek(String.valueOf(week))
            );
        }
        callBack(true);
    }

    // 恶性负载事件有功功率触发下限
    @Override
    public void writeMalignantLoadLimit() {
        callBack(true);
    }

    // 恶性负载事件有功功率触发下限
    @Override
    public void readMalignantLoadLimit(BigDecimal w) {

    }

    // 启用违规用电的功率下限
    @Override
    public void writeViolationsPower() {
        callBack(true);
    }

    // 启用违规用电的功率下限
    @Override
    public void readViolationsPower(BigDecimal w) {
        callBack(true);
    }

    @Override
    public void readSinglePowerState(int state) {
        callBack(true);
    }

    // 有功功率负荷限值
    @Override
    public void writeUseElectricity() {
        callBack(true);
    }

    // 有功功率负荷限值
    @Override
    public void readUseElectricity(BigDecimal w) {
        if (tParamUeService != null) {
            tParamUeService.updateByRoomIdSelective(new TparamUe().setRoomId(roomId).setMaxZgl(w).setUpdateDt(LocalDateTime.now()));
        }
        callBack(true);
    }

    // 定时断送电
    @Override
    public void writePeriods(int runType) {
        if (tParamTpService != null) {
            tParamTpService.updateByRoomIdSelective(tparamTp != null ? tparamTp.setRunType(runType).setUpdateDt(LocalDateTime.now())
                    : new TparamTp().setRoomId(roomId).setUpdateDt(LocalDateTime.now()).setRunType(runType)
            );
        }
        callBack(true);
    }

    // 定时断送电 时间格式：HHmm
    @Override
    public void readPeriods(int state1, String time1, int state2, String time2) {
        callBack(true);
        if (tParamTpService != null) {
            TparamTp tparamTp = new TparamTp().setRoomId(roomId).setRunType(1).setUpdateDt(LocalDateTime.now());
            LocalDate now = LocalDate.now();
            switch (now.getDayOfWeek().getValue()) {
                case 1: {
                    tparamTp.setSdt1State(state1).setSdt1(time1).setEdt1State(state2).setEdt1(time2);
                }
                break;
                case 2: {
                    tparamTp.setSdt2State(state1).setSdt2(time1).setEdt2State(state2).setEdt2(time2);
                }
                break;
                case 3: {
                    tparamTp.setSdt3State(state1).setSdt3(time1).setEdt3State(state2).setEdt3(time2);
                }
                break;
                case 4: {
                    tparamTp.setSdt4State(state1).setSdt4(time1).setEdt4State(state2).setEdt4(time2);
                }
                break;
                case 5: {
                    tparamTp.setSdt5State(state1).setSdt5(time1).setEdt5State(state2).setEdt5(time2);
                }
                break;
                case 6: {
                    tparamTp.setSdt6State(state1).setSdt6(time1).setEdt6State(state2).setEdt6(time2);
                }
                break;
                case 7: {
                    tparamTp.setSdt7State(state1).setSdt7(time1).setEdt7State(state2).setEdt7(time2);
                }
                break;
            }
            tParamTpService.updateByRoomIdSelective(tparamTp);
        }
    }

    @Override
    public void readPeriods() {
        callBack(true);
        if (tParamTpService != null) {
            tParamTpService.updateByRoomIdSelective(new TparamTp().setRoomId(roomId).setRunType(0).setUpdateDt(LocalDateTime.now()));
        }
    }

    @Override
    public void writeAddress() {
        callBack(true);
    }

    @Override
    public void readAddress(short address) {
        callBack(true);
    }

    @Override
    public void writeRebootTime() {
        callBack(true);
    }

    @Override
    public void readRebootTime(short time) {
        callBack(true);
    }

    @Override
    public void readRelaysRealState(int state) {
        if (tdataRtRsService != null) {
            tdataRtRsService.updateByRoomIdSelective(new TdataRtRs().setRoomId(roomId).setRunStatus(1).setWorkStatus(state)
                    .setDt(LocalDateTime.now()));
        }
        callBack(true);
    }

    @Override
    public void callBackFail() {
        log.info("roomId " + roomId + " callBackFail");
        if (tdataRtRsService != null) {
            tdataRtRsService.updateByRoomIdSelective(new TdataRtRs().setRoomId(roomId).setRunStatus(4)
                    .setDt(LocalDateTime.now()));
        }
        if (tParamUeService != null) {
            tParamUeService.updateByRoomIdSelective(new TparamUe().setRoomId(roomId).setRunStatus(4)
                    .setUpdateDt(LocalDateTime.now()));
        }
//        if (tdataRtRsService != null) {
//            tdataRtRsService.updateByRoomIdSelective(new TdataRtWgc().setRoomId(roomId).setRunStatus(4)
//                    .setDt(LocalDateTime.now()));
//        }
        if (tparamEqService != null) {
            tparamEqService.updateByRoomIdSelective(new TparamEq().setRoomId(roomId).setRunStatus(4)
                    .setUpdateDt(LocalDateTime.now()));
        }
        if (tParamTmService != null) {
            tParamTmService.updateByRoomIdSelective(new TparamTm().setRoomId(roomId).setRunStatus(4)
                    .setUpdateDt(LocalDateTime.now()));
        }
        if (tParamTpService != null) {
            tParamTpService.updateByRoomIdSelective(new TparamTp().setRoomId(roomId).setRunStatus(4)
                    .setUpdateDt(LocalDateTime.now()));
        }
        callBack(false);
    }
}
